﻿#region - Class details -
/*  
 *  Developer   : Wicus Botha
 *  Description : 
 *  History     : WB - 2008-10-20 - Created
 */
#endregion

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using IQ.DbBase;

namespace SqlServerAdmin
{
    public class SqlMdFileData
    {
        private static readonly SqlMdFileData instance = new SqlMdFileData();

        #region # Constructor #
        private SqlMdFileData()
        {
            mdDataSet = DbHelper.LoadDataSetFromFile(mdFileName);
            dsExtentions = DbHelper.LoadDataSetFromFile(dbFileExtention);
            if (dsExtentions == null)
                createExtensionDataSet();
        }
        #endregion

        #region - Private variables -
        private const string FnDataBaseName = "DataBaseName";

        #region - Meta data -- Info
        private DataSet mdDataSet;
        private const string mdFileName = "sqlamd.cz";
        private const string mdTables = "dtTables";
        private const string mdFields = "dtFields";
        //private const string mdRelations = "dtRI";
        private const string mdSps = "dtSps";
        private const string mdIndexes = "dtIx";
        private const string mdIndexFields = "dtIxFields";
        // File Table indexes
        private const byte tiTables = 0;
        private const byte tiFields = 1;
        private const byte tiSp = 2;
        private const byte tiIndex = 3;
        private const byte tiIndexFields = 4;
        #endregion

        #region - Extentions -- Info
        private DataSet dsExtentions;
        private const string dbFileExtention = "sqlaex.cz";
        private const byte tiExclusions = 0;
        private const string FnExclusions = "ExclusionList";
        #endregion
        #endregion

        #region - Private methods -
        private void createExtensionDataSet()
        {
            dsExtentions = new DataSet();
            // DataTable - Exclusions
            DataTable dtExclude = new DataTable();
            DbHelper.AddDataColumn(dtExclude, FnDataBaseName, "System.String", true, "");
            DbHelper.AddDataColumn(dtExclude, FnExclusions, "System.String", false, 0);
            //
            dsExtentions.Tables.Add(dtExclude);
        }
        private DataView viewForType(string nameType)
        {
            return new DataView(mdDataSet.Tables[tiTables], SqlQueries.Field_Type + "='" + nameType + "'", SqlQueries.Field_Name, DataViewRowState.CurrentRows);
        }
        private string getObjectTextFromDataRows(DataRow[] rows)
        {
            if (rows != null && rows.Length > 0)
            {
                if (rows.Length == 1)
                    return rows[0][SqlQueries.Field_ObjectText].ToString();
                else
                {
                    string tmpText = rows[0][SqlQueries.Field_ObjectText].ToString();
                    for (int i = 1; i < rows.Length; ++i)
                        tmpText += rows[i][SqlQueries.Field_ObjectText].ToString();
                    return tmpText;
                }
            }
            else
                return "";
        }
        #endregion

        #region - Public properties / variables -
        public static SqlMdFileData Instance
        {
            get { return instance; }
        }
        public DataTable FileTables
        {
            get { return viewForType(SqlQueries.SoT_Tables).ToTable(); }
        }
        public DataTable FileFields
        {
            get { return mdDataSet.Tables[tiFields]; }
        }
        public DataTable FileStoreProc
        {
            get { return viewForType(SqlQueries.SoT_StoreProc).ToTable(); }
        }
        public DataTable FileIndexes
        {
            get { return mdDataSet.Tables[tiIndex]; }
        }
        public DataTable FileIndexFields
        {
            get { return mdDataSet.Tables[tiIndexFields]; }
        }        
        #endregion

        #region - Public methods -
        public static bool CheckCompareFileExists()
        {
            return File.Exists(mdFileName);
        }
        public static void SaveMetaData()
        {
            DataSet md = new DataSet();
            SqlDataAdapter dap = new SqlDataAdapter(SqlQueries.GetSqlMdSystemObjects(), (SqlConnection)DbHelper.GetConnection());
            dap.Fill(md, mdTables);
            dap = new SqlDataAdapter(SqlQueries.GetSqlMdTableFields(), (SqlConnection)DbHelper.GetConnection());
            dap.Fill(md, mdFields);
            dap = new SqlDataAdapter(SqlQueries.GetSqlMd_SVF(), (SqlConnection)DbHelper.GetConnection());
            dap.Fill(md, mdSps);
            //
            dap = new SqlDataAdapter(SqlQueries.GetSqlMdTableKeys(), (SqlConnection)DbHelper.GetConnection());
            dap.Fill(md, mdIndexes);
            dap = new SqlDataAdapter(SqlQueries.GetSqlMdTableKeysFields(), (SqlConnection)DbHelper.GetConnection());
            dap.Fill(md, mdIndexFields);
            //
            DbHelper.SaveDataSetToFile(md, mdFileName);
        }
        public void RefreshFileData()
        {
            mdDataSet = DbHelper.LoadDataSetFromFile(mdFileName);
        }
        public DataTable NamesForType(string nameType)
        {
            return viewForType(nameType).ToTable();
        }
        public DataRow FileNameForType(string nameType, string name)
        {
            return mdDataSet.Tables[tiTables].Select(SqlQueries.Field_Type + "='" + nameType + "' AND " +
                 SqlQueries.Field_Name + "='" + name + "'").FirstOrDefault();
        }
        public DataRow[] FileNamesForType(string nameType)
        {
            return mdDataSet.Tables[tiTables].Select("Type='" + nameType + "'");
        }
        public string GetFileObjectText(string nameType, string name)
        {
            DataRow[] drFileData = mdDataSet.Tables[tiSp].Select(SqlQueries.Field_Type + "='" + nameType + "' AND " 
                + SqlQueries.Field_Name + "='" + name + "'");
            //
            if (drFileData != null && drFileData.Length > 0)
            {
                return getObjectTextFromDataRows(drFileData);
            }
            return "";
        }
        // Eclusions
        public string[] GetExcludeList(string dbName)
        { 
            DataRow dr = dsExtentions.Tables[tiExclusions].Select(FnDataBaseName + "='" + dbName + "'").FirstOrDefault();
            if (dr != null)
            {
                return dr[FnExclusions].ToString().Split(',');
            }
            else
                return null;
        }
        public bool CheckExclusions(string[] exclusions, string nameToCheck)
        {
            string findIt = exclusions.Where(x => x.StartsWith(nameToCheck)).FirstOrDefault();
            return !String.IsNullOrEmpty(findIt);
        }
        public bool SaveExludeList(string dbName, string[] list)
        {
            if (list.Length > 0)
            {
                DataRow dr = dsExtentions.Tables[tiExclusions].Select(FnDataBaseName + "='" + dbName + "'").FirstOrDefault();
                if (dr == null)
                { 
                    dr = dsExtentions.Tables[tiExclusions].NewRow();
                    dr[FnDataBaseName] = dbName;
                    dsExtentions.Tables[tiExclusions].Rows.Add(dr);
                }
                string[] cleanList = list.Where(x => !String.IsNullOrEmpty(x)).ToArray();
                if (!cleanList.SequenceEqual(list))
                {
                    dr[FnExclusions] = String.Join(",", cleanList);
                    DbHelper.SaveDataSetToFile(dsExtentions, dbFileExtention);
                    return true;
                }
            }
            return false;
        }
        #endregion
    }
}
